package com.dingyx.ps.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSONObject;
import com.dingyx.ps.model.vo.AccountBillSlaverForApiVO;
import com.dingyx.ps.model.vo.EngineerForApiVO;
import com.dingyx.ps.util.ApiUtil;
import com.dingyx.ps.util.EncryptUtil;
import com.dingyx.ps.util.HttpUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * @author dingyuxin
 * apidemo
 */
@Slf4j
public class OpenApiClient {

    private String mchId;

    private String chanId;

    private String protoId;

    private String appKey;

    private String callBackUrl;

    public OpenApiClient(String mchId,
                         String chanId,
                         String protoId,
                         String appKey,
                         String callBackUrl) {
        this.mchId = mchId;
        this.chanId = chanId;
        this.protoId = protoId;
        this.appKey = appKey;
        this.callBackUrl = callBackUrl;
    }

    /**
     * 申请访问权限token令牌
     *
     * @return
     * @throws Exception
     */
    public JSONObject applyToken(String applyToken) throws Exception {
        // 接口类型type：0签约，1确认签约，2签约查询，3平台结算，4确认结算，5订单查询，6余额查询
        String nonceStr = ApiUtil.rundom3();
        String timestamp = String.valueOf(DateUtil.currentSeconds());
        // 组装请求参数，作为requestbody
        JSONObject requestBody = new JSONObject();
        requestBody.put("nonce_str", nonceStr);
        requestBody.put("timestamp", timestamp);
        requestBody.put("sign", ApiUtil.sortAndEncrypt(nonceStr,timestamp,appKey));
        requestBody.put("key",appKey);
        requestBody.put("mch_id", mchId);
        JSONObject datas = new JSONObject();
        datas.put("type","3");
        // type为3时必传
        datas.put("callBackUrl",callBackUrl);
        // type为3时必传
        datas.put("chan_id", chanId);
        String paramData = EncryptUtil.rsaEncrypt(datas.toString(), appKey);
        requestBody.put("data",paramData);
        // 发送请求
        JSONObject obj = HttpUtil.jsonPost(applyToken, requestBody);
        // 返回code为200，表示成功，其他表示失败
        if (Objects.isNull(obj)){
            throw new Exception("调用椰云生成token失败");
        }
        if (obj.getInteger("code") == 200) {
            JSONObject data = obj.getJSONObject("data");
            if (data != null) {
                return data;
            }
            return null;
        } else {
            throw new Exception("code="+obj.getInteger("code") +" msg="+ obj.getString("msg"));
        }
    }

    /**
     * 获取batch
     *
     * @return
     * @throws Exception
     */
    public JSONObject getBatch(String token, String getBatch) throws Exception {
        // 接口类型type：0签约，1确认签约，2签约查询，3平台结算，4确认结算，5订单查询，6余额查询
        String nonceStr = ApiUtil.rundom3();
        String timestamp = String.valueOf(DateUtil.currentSeconds());
        // 组装请求参数，作为requestbody
        JSONObject requestBody = new JSONObject();
        requestBody.put("nonce_str", nonceStr);
        requestBody.put("timestamp", timestamp);
        requestBody.put("sign", ApiUtil.sortAndEncrypt(nonceStr,timestamp,appKey));
        requestBody.put("key",appKey);
        requestBody.put("mch_id", mchId);
        JSONObject datas = new JSONObject();
        datas.put("callBackUrl",callBackUrl);
        // type为3时必传
        datas.put("chan_id", chanId);
        datas.put("token",token);
        String paramData = EncryptUtil.rsaEncrypt(datas.toString(), appKey);
        requestBody.put("data",paramData);
        // 发送请求
        JSONObject obj = HttpUtil.jsonPost(getBatch, requestBody);
        if (Objects.isNull(obj)){
            throw new Exception("调用椰云生成token失败");
        }
        // 返回code为200，表示成功，其他表示失败
        if (obj.getInteger("code") == 200) {
            JSONObject data = obj.getJSONObject("data");
            if (data != null) {
                return data;
            }
            return null;
        } else {
            throw new Exception("code="+obj.getInteger("code") +" msg="+ obj.getString("msg"));
        }
    }

    /**
     * 调用接口
     *
     * @return
     * @throws Exception
     */
    public JSONObject externalApiStep1(String token, String type, EngineerForApiVO dto, String externalApi){
        String batch = null;
        // 接口类型type：0签约，1确认签约，2签约查询，3平台结算，4确认结算，5订单查询，6余额查询
        String nonceStr = ApiUtil.rundom3();
        String timestamp = String.valueOf(DateUtil.currentSeconds());
        // 组装请求参数，作为requestbody
        JSONObject requestBody = new JSONObject();
        requestBody.put("nonce_str", nonceStr);
        requestBody.put("timestamp", timestamp);
        requestBody.put("sign", ApiUtil.sortAndEncrypt(nonceStr,timestamp,appKey));
        requestBody.put("key",appKey);
        requestBody.put("mch_id", mchId);
        JSONObject datas = new JSONObject();
        if (Objects.equals(type, "0")){
            /**
             * type = 0：签约请求
             * 注意：手机号不做校验，姓名+身份证+银行卡必须真实
             *
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("name", dto.getEngineerName());
            datas.put("phone", dto.getRegisterMobile());
            datas.put("id_card", dto.getIdNumber());
            datas.put("card_no", dto.getBrandCardNumber());
            datas.put("proto_id", protoId);
            // 是否使用支付宝方式结算（是:此字段必传{格式："ALIPAY":"ALIPAY"}，否:不传）
//            datas.put("ALIPAY","ALIPAY");
        } else if (Objects.equals(type, "1")){
            /**
             * type = 1：确认签约
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("proto_id", protoId);
        } else if (Objects.equals(type, "2")){
            /**
             * type = 2：签约查询
             * id_card：手机号
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("proto_id", protoId);
            datas.put("id_card", dto.getIdNumber());
        }

        String paramData = EncryptUtil.rsaEncrypt(datas.toString(), appKey);
        requestBody.put("data",paramData);
        // 发送请求
        JSONObject obj = null;
        try {
            obj = HttpUtil.jsonPost(externalApi, requestBody);
            return obj;
        } catch (Exception e) {
            log.info("人员签约异常:{}", ExceptionUtil.getMessage(e));
        }
        return obj;

    }

    /**
     * 调用接口
     *
     * @return
     * @throws Exception
     */
    public JSONObject externalApiStep2(String token, String type, String batch, AccountBillSlaverForApiVO vo, String externalApi) {
        // 测试第三方接口：接口类型type：0签约，1确认签约，2签约查询，3平台结算，4确认结算，5订单查询，6余额查询
        String nonceStr = ApiUtil.rundom3();
        String timestamp = String.valueOf(DateUtil.currentSeconds());
        // 组装请求参数，作为requestbody
        JSONObject requestBody = new JSONObject();
        requestBody.put("nonce_str", nonceStr);
        requestBody.put("timestamp", timestamp);
        requestBody.put("sign", ApiUtil.sortAndEncrypt(nonceStr,timestamp,appKey));
        requestBody.put("key",appKey);
        requestBody.put("mch_id", mchId);
        JSONObject datas = new JSONObject();
        if (Objects.equals(type, "3")){
            /**
             * type = 3：平台结算
             * 1，生成批次
             * 2，返回批次值后，赋值到type = 3的batch字段，type = 4的入参也需要和type = 3使用的batch相同
             * 3，交易订单号trade_no是灵活用的唯一单号
             * 4，type = 3执行成功返回的信息有：pay_no（平台单号）
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("batch", batch);
            datas.put("trade_no", vo.getBillNo());
            datas.put("chan_id", chanId);
            datas.put("id_card", vo.getIdNumber());
            datas.put("name", vo.getEngineerName());
            datas.put("phone", vo.getRegisterMobile());
            datas.put("card_no", vo.getBrandCardNumber());
            datas.put("pay_amount", vo.getTaskUnitPriceActual());
            // 是否使用支付宝方式结算（是:此字段必传{格式："ALIPAY":"ALIPAY"}，否:不传）
//            datas.put("ALIPAY","ALIPAY");
//            datas.put("remarks","测试数据");
        } else if (Objects.equals(type, "4")){
            /**
             * type = 4：确认结算
             * 批次batch：是 type = 3使用的batch
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("batch", batch);
        } else if (Objects.equals(type, "5")){
            /**
             * type = 5：订单查询
             * 1，批次batch：是 type = 3使用的batch
             * 2，平台订单号pay_no：由type=3返回得到
             * 3，交易订单号trade_no：灵活用的唯一单号
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("batch", "JA1403192015013l");
            datas.put("pay_no","JA1403192015013l98mg6o");
            datas.put("trade_no","wrj20210319001");
        } else if (Objects.equals(type, "6")){
            /**
             * type = 6：账户余额
             */
            datas.put("type", type);
            datas.put("token",token);
            datas.put("mch_id", mchId);
            datas.put("chan_id", chanId);
        }

        String paramData = EncryptUtil.rsaEncrypt(datas.toString(), appKey);
        requestBody.put("data",paramData);
        // 发送请求
        JSONObject obj = null;
        try {
            obj = HttpUtil.jsonPost(externalApi, requestBody);
        } catch (Exception e) {
            log.error("结算单处理异常->{}", ExceptionUtil.getMessage(e));
        }
        return obj;
    }
}
